package se.webbzon.boltzmann.editor.comparator;

import java.util.Comparator;

import se.webbzon.boltzmann.object.geometry.Geometry;
import se.webbzon.oschi01.worldeditor.DeflatableWorldObject;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public class WorldObjectComparator implements Comparator<WorldObject> {
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public int compare(WorldObject left, WorldObject right) {
		if (left instanceof Geometry && right instanceof Geometry)
			return compareInner((Geometry) left, (Geometry) right);
		else if (	left instanceof DeflatableWorldObject && 
					right instanceof DeflatableWorldObject)
			return compareInner((DeflatableWorldObject) left, (DeflatableWorldObject) right);
		else if (left instanceof WorldStaticObject && right instanceof WorldStaticObject)
			return compareInner((WorldStaticObject) left, (WorldStaticObject) right);
		else
			return compareInner(left,right);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Compares two geometries. **/
	private static final int compareInner(Geometry left, Geometry right) {
		int cmp = left.getGeometryAppearance().getTextureSetName().
				compareTo(right.getGeometryAppearance().getTextureSetName());
		if (cmp == 0)
			return compareInner((WorldStaticObject) left, (WorldStaticObject) right);
		else
			return cmp;
	}
	
	/** Compares two deflatable world objects. **/
	private static final int compareInner(DeflatableWorldObject left, DeflatableWorldObject right) {
		int cmp = left.getName().compareTo(right.getName());
		if (cmp == 0) {
			if (left instanceof WorldStaticObject && right instanceof WorldStaticObject)
				return compareInner((WorldStaticObject) left, (WorldStaticObject) right);
			else
				return compareInner((WorldObject) left, (WorldObject) right);
		} else
			return cmp;
	}
	
	/** Compares two static world objects. **/
	private static final int compareInner(WorldStaticObject left, WorldStaticObject right) {
		final int x = (int) (left.getX() - right.getX());
		if (x == 0) {
			// Sort by y
			final int y = (int) (left.getY() - right.getY());
			if (y == 0) {
				// Sort by z
				final int z = (int) (left.getZ() - right.getZ());
				if (z == 0)
					return compareInner((WorldObject) left, (WorldObject) right);
				else
					return z;
			} else
				return y;
		} else
			return x;
	}
	
	/** Compares two world objects. **/
	private static final int compareInner(WorldObject left, WorldObject right) {
		return left.hashCode() - right.hashCode();
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** A geometry comparator. **/
	/*private static final class GeometryComparator implements Comparator<Geometry> {

		@Override public int compare(Geometry left, Geometry right) {
			return compareInner(left,right);
		}
		
	}*/
	
	/** A static world object comparator. **/
	/*private static final class WorldStaticObjectComparator implements Comparator<WorldStaticObject> {

		@Override public int compare(WorldStaticObject left, WorldStaticObject right) {
			return compareInner(left,right);
		}
		
	}*/
	
	
}
